package com.ruoyi.activity.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.activity.domian.RedPacketRecord;
import com.ruoyi.activity.entity.RedPacketRecordQuery;
import com.ruoyi.activity.enumuration.RedPacketRecordViewEnum;
import com.ruoyi.activity.mapper.RedPacketRecordDao;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.DataSourceType;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 红包记录
 * @author chengjian 
 * @date 2021/9/10
 */
@Service
@DataSource(DataSourceType.SLAVE)
public class RedPacketRecordService {
    @Resource
    private RedPacketRecordDao redPacketRecordDao;

    public Page<RedPacketRecord> list(RedPacketRecordQuery query){
        return redPacketRecordDao.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), query.getQuery());
    }

    public AjaxResult view(RedPacketRecordQuery query){
        Date today = new Date();
        LambdaQueryWrapper<RedPacketRecord> queryWrapper = query.getViewQuery(today);
        if (queryWrapper ==  null){
            return AjaxResult.error(201,"勾选时间不能超过60天");
        }

        AjaxResult ajaxResult = new AjaxResult();
        List<RedPacketRecord> list = redPacketRecordDao.selectList(queryWrapper);
        if (CollUtil.isEmpty(list)){
            return ajaxResult;
        }

        List<String> sendDateList = new ArrayList<>();

        // 发送红包金额
        List<Long> sumList = new ArrayList<>();
        // 领取金额
        List<Long> gainList = new ArrayList<>();
        // 剩余金额
        List<Long> surplusList = new ArrayList<>();

        Map<String,List<RedPacketRecord>> recordsMap = list.stream()
                .collect(Collectors.groupingBy(RedPacketRecord::getSendDate,Collectors.collectingAndThen(Collectors.toList(),v->v)));

        Date pre = null;
        if (StringUtils.isNotEmpty(query.getEndTime())){
            pre = DateUtil.parse(query.getEndTime());
        }

        if (query.getOption() != null){
            int liveNum = 0;
            if (query.getOption().equals(RedPacketRecordViewEnum.LIVE_CHANNEL.getOption())){
                liveNum = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RedPacketRecord::getRoomId))), ArrayList::new)).size();
            }
            return getSingleView(query,today,pre,liveNum,recordsMap);
        }

        for (int i = 0; i < query.getXAxisNum(); i++){
            String date = getDate(today, pre, query.getEndTime(), query.getXAxisNum(), i);
            List<RedPacketRecord> records = recordsMap.get(date);
            if (CollUtil.isEmpty(records)){
                sendDateList.add(date);
                sumList.add(0L);
                gainList.add(0L);
                surplusList.add(0L);
                continue;
            }

            sendDateList.add(date);

            Long sum = records.stream().mapToLong(RedPacketRecord::getSendMoney).sum() / 100;
            sumList.add(sum);

            Long gain = records.stream().mapToLong(RedPacketRecord::getGainMoney).sum() / 100;
            gainList.add(gain);

            Long surplus = records.stream().mapToLong(RedPacketRecord::getSurplusMoney).sum() / 100;
            surplusList.add(surplus);
        }


        Long moneySum = sumList.stream().mapToLong(Long::new).sum();
        Long gainSum = gainList.stream().mapToLong(Long::new).sum();
        Long surplusSum = surplusList.stream().mapToLong(Long::new).sum();
        int liveNum = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RedPacketRecord::getRoomId))), ArrayList::new)).size();

        Map<String,Long> moneyMap = new HashMap<>(8);
        moneyMap.put("total",moneySum);
        moneyMap.put("gain",gainSum);
        moneyMap.put("surplus",surplusSum);
        moneyMap.put("liveNum", (long) liveNum);


        Map<String,Object> map = new HashMap<>(8);
        map.put("xAxis",sendDateList);
        map.put("sumList",sumList);
        map.put("gain",gainList);
        map.put("surplus",surplusList);
        map.put("names",RedPacketRecordViewEnum.getOptionsLabel());

        ajaxResult.put("data",map);
        ajaxResult.put("moneys",moneyMap);
        return ajaxResult;
    }

    private AjaxResult getSingleView(RedPacketRecordQuery query, Date today, Date pre, int num, Map<String,List<RedPacketRecord>> recordsMap){
        List<String> sendDateList = new ArrayList<>();
        // 数据
        List<Long> dataList = new ArrayList<>();

        for (int i = 0; i < query.getXAxisNum(); i++){
            String date = getDate(today, pre, query.getEndTime(), query.getXAxisNum(), i);

            List<RedPacketRecord> records = recordsMap.get(date);
            if (CollUtil.isEmpty(records)){
                sendDateList.add(date);
                dataList.add(0L);
                continue;
            }

            sendDateList.add(date);

            if (query.getOption() == 4){
                List<RedPacketRecord> newList = records.stream()
                        .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RedPacketRecord::getRoomId))), ArrayList::new));
                dataList.add((long) newList.size());
            } else if (query.getOption() == 3){
                Long sum = records.stream().mapToLong(RedPacketRecord::getSendMoney).sum() / 100;
                dataList.add(sum);
            } else if (query.getOption() == 2){
                Long gain = records.stream().mapToLong(RedPacketRecord::getGainMoney).sum() / 100;
                dataList.add(gain);
            } else if (query.getOption() == 1){
                Long surplus = records.stream().mapToLong(RedPacketRecord::getSurplusMoney).sum() / 100;
                dataList.add(surplus);
            }
        }
        long dataCount;
        if (query.getOption().equals(RedPacketRecordViewEnum.LIVE_CHANNEL.getOption())){
            dataCount = num;
        } else {
            dataCount = dataList.stream().mapToLong(Long::new).sum();
        }

        Map<String,Long> moneyMap = new HashMap<>(8);
        moneyMap.put("total",dataCount);


        Map<String,Object> map = new HashMap<>(8);
        map.put("xAxis",sendDateList);
        map.put("sumList",dataList);
        map.put("names",Collections.singletonList(RedPacketRecordViewEnum.getLabelName(query.getOption())));

        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("data",map);
        ajaxResult.put("moneys",moneyMap);
        return ajaxResult;
    }

    private String getDate(Date today, Date pre, String endTime, int num, int index){
        String date;
        if (StringUtils.isNotEmpty(endTime)){
            date = DateUtil.format(DateUtil.offsetDay(pre,index - num), DatePattern.PURE_DATE_PATTERN);
        }else {
            date = DateUtil.format(DateUtil.offsetDay(today,index - num), DatePattern.PURE_DATE_PATTERN);
        }
        return date;
    }
 }
